package com.cbtx.tablet

import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import com.blankj.utilcode.util.AppUtils
import com.cbtx.mvvm.BaseApp
import com.cbtx.networklib.ApiServiceHolder
import com.cbtx.networklib.config.HostConfig
import com.cbtx.tablet.constant.HttpConstant
import com.cbtx.tablet.device.MachineFactory
import com.cbtx.tablet.net.ApiService
import com.cbtx.tablet.ui.AppManager
import com.cbtx.utils.DeviceUtil
import com.cbtx.utils.NetWorkUtil
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

/**
 * author : joker.peng
 * e-mail : joker@fiture.com
 * date   : 2021/7/1 2:01 PM
 * desc   :
 */
class App : BaseApp() {

    companion object {
        lateinit var instance: Application
        var bootTime: Long = System.currentTimeMillis()
        lateinit var sApiServiceHolder: ApiServiceHolder<ApiService>
        lateinit var androidId: String
    }

    override fun onCreate() {
        super.onCreate()

        ignoreSSLHandshake()

        setActivityLifeCycle()
        instance = this
        androidId = DeviceUtil.getSerialNumber(this)

        initNetwork()
    }

    private fun initNetwork() {

        FileDownloader.setupOnApplicationOnCreate(this)
            .connectionCreator(
                FileDownloadUrlConnection.Creator(
                    FileDownloadUrlConnection.Configuration()
                        .connectTimeout(15000) // set connection timeout.
                        .readTimeout(15000) // set read timeout.
                )
            )
            .commit()

        val hostConfig: HostConfig = HostConfig.Builder()
            .addHostEntry(
                HttpConstant.CONTENT_ALIAS, HostConfig.HostEntry(
                    HttpConstant.PRO, HttpConstant.QA, HttpConstant.DEV
                )
            ).build()

        sApiServiceHolder = ApiServiceHolder(
            this,
            ApiService::class.java,
            hostConfig,
            headers = getHeaderMap()
        )
        if (BuildConfig.DEBUG) {
            sApiServiceHolder.env = HostConfig.Env.DEV
        } else {
            sApiServiceHolder.env = HostConfig.Env.PROD
        }
    }

    private fun setActivityLifeCycle() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
                AppManager.addActivity(activity)
            }

            override fun onActivityStarted(activity: Activity) {}
            override fun onActivityResumed(activity: Activity) {}
            override fun onActivityPaused(activity: Activity) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
            override fun onActivityDestroyed(activity: Activity) {
                AppManager.removeActivity(activity)
            }
        })
    }


    fun getApiService(alisa: String): ApiService {
        return sApiServiceHolder.getApiService(alisa)
    }

    fun getHeaderMap(): MutableMap<String, String?> {
        var map = mutableMapOf<String, String?>()
        var iMachine = MachineFactory.getAutoCreate(this)
        map["uniquedevicecode"] = iMachine.uniqueDeviceCode
        map["appversion"] = AppUtils.getAppVersionCode().toString()
        map["appversioncode"] = versionName(this)
        map["firmwareversion"] = iMachine.frameworkVersion
        map["devicemodel"] = iMachine.model
        map["screenType"] = "INTERACTIVE"
        map["manualReg"] = "true"
        map["mac"] = iMachine.localMac
        map["producttype"] = iMachine.getProductType()
        map["serial"] = androidId
        map["networkingWay"] = NetWorkUtil.getNetWorkState(this).toString()
        return map
    }

    fun ignoreSSLHandshake() {
        try {
            val trustAllCerts =
                arrayOf<TrustManager>(object : X509TrustManager {
                    override fun getAcceptedIssuers(): Array<X509Certificate?>? {
                        return arrayOfNulls(0)
                    }

                    override fun checkClientTrusted(
                        certs: Array<X509Certificate?>?,
                        authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                        certs: Array<X509Certificate?>?,
                        authType: String?
                    ) {
                    }
                })
            val sc = SSLContext.getInstance("TLS")
            // trustAllCerts信任所有的证书
            sc.init(null, trustAllCerts, SecureRandom())
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)
            HttpsURLConnection.setDefaultHostnameVerifier { hostname, session -> true }
        } catch (e: java.lang.Exception) {
        }
    }

    fun versionName(context: Context): String {
        val manager = context.packageManager
        var name = ""
        try {
            val info = manager.getPackageInfo(context.packageName, 0)
            name = info.versionName
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        var listStr = name.split(".")
        var result = ""
        listStr.forEach {
            result += it
        }
        return result
    }
}